local AddOnName, Env = ...; local ADDON, DEV = Env[1], Env[1].DEV
-- | Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local LibDBIcon					= LibStub("LibDBIcon-1.0",true)
local AceDB							= LibStub("AceDB-3.0")
local AceDBOptions 			= LibStub("AceDBOptions-3.0")
local AceConfigRegistry	= LibStub("AceConfigRegistry-3.0")
local AceConfigDialog 	= LibStub("AceConfigDialog-3.0")
local LibDataBroker			= LibStub("LibDataBroker-1.1")
local LibDBIcon 				= LibStub("LibDBIcon-1.0",true)
-- | Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local select, print							= select, print
local type, tostring, tonumber	= type, tostring, tonumber
local getmetatable							= getmetatable
local sub, find, format, split	= string.sub, string.find, string.format, string.split
local floor 										= math.floor
local remove 										= table.remove
-- | WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local GetSpellInfo, GetTime  		= GetSpellInfo, GetTime
-- | Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-- | Event Handlers |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ADDON:UPDATE_BINDINGS(...)
	ADDON.RotationSelecter.HKAutoButton1:SetText( GetBindingKey('CLICK HKAutoButton1:LeftButton'))
	ADDON.RotationSelecter.HKAutoButton2:SetText( GetBindingKey('CLICK HKAutoButton2:LeftButton'))
	ADDON.RotationSelecter.HKAutoButton3:SetText( GetBindingKey('CLICK HKAutoButton3:LeftButton'))
	ADDON.RotationSelecter.HKAutoButton4:SetText( GetBindingKey('CLICK HKAutoButton4:LeftButton'))
	ADDON.RotationSelecter.HKAutoButton5:SetText( GetBindingKey('CLICK HKAutoButton5:LeftButton'))
	ADDON.RotationSelecter.HKAutoButton6:SetText( GetBindingKey('CLICK HKAutoButton6:LeftButton'))
	ADDON.RotationSelecter.HKManualButton1:SetText( GetBindingKey('CLICK HKManualButton1:LeftButton'))
	ADDON.RotationSelecter.HKManualButton2:SetText( GetBindingKey('CLICK HKManualButton2:LeftButton'))
	ADDON.RotationSelecter.HKManualButton3:SetText( GetBindingKey('CLICK HKManualButton3:LeftButton'))
	ADDON.RotationSelecter.HKManualButton4:SetText( GetBindingKey('CLICK HKManualButton4:LeftButton'))
	ADDON.RotationSelecter.HKManualButton5:SetText( GetBindingKey('CLICK HKManualButton5:LeftButton'))
end
-- | ADDON States |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ADDON:OnInitialize()
	-- Database ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	self.db = AceDB:New(AddOnName.."DB", self.defaults, true);
	self.db.RegisterCallback(self, "OnProfileChanged", "ProfileUpdate")
	self.db.RegisterCallback(self, "OnProfileCopied", "ProfileUpdate")
	self.db.RegisterCallback(self, "OnProfileReset", "ProfileUpdate")
	-- Options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	self.options.args.profile = AceDBOptions:GetOptionsTable(self.db)
	self.options.args.profile.order = -10
	AceConfigRegistry:RegisterOptionsTable(AddOnName, ADDON.options)
	AceConfigDialog:AddToBlizOptions(AddOnName, nil, nil, "settings")
	AceConfigDialog:AddToBlizOptions(AddOnName, "Profiles", AddOnName, "profile")
	-- DataBroker Launcher Plugin ~~~~~~~~~~~~~~~~~
	self.launcher = LibDataBroker:NewDataObject(AddOnName,{
		type 				= "launcher",
		label 			= AddOnName,
		icon 				= ADDON.MEDIAPATH.."LDBIcon",
		OnClick 			= function(this,button)
			ADDON:OpenOptions()
		end,
		OnTooltipShow = function(tooltip)
			tooltip:AddLine(AddOnName, 0, .66, 1)
			tooltip:AddLine(" ")
			tooltip:AddDoubleLine("Click:","Open Config", 0, .66, 1, 1, .83, 0)
		end,
	})
	-- Update ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	LibDBIcon:Register(AddOnName,self.launcher,self.db.global.minimap)
	-- Slash commands ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	self:RegisterChatCommand(AddOnName:lower(),'CommandHandler')
	-- Module Construction ~~~~~~~~~~~~~~~~~~~~~~~~
	self.Remote 				= ADDON:constructRemote()
	self.RotationSelecter 	= ADDON:constructRotationSelecter()
	self.Engine 				= ADDON:constructEngine()
	self.ActionLog 			= ADDON:constructActionLog()
	self.Tracker 				= ADDON:constructTracker()
	-- FireHack Initialize ~~~~~~~~~~~~~~~~~~~~~~~~
	if FireHack then
		self:OnFireHack()
	else
		local check = CreateFrame('Frame')
		check:SetScript('OnUpdate', function(this,elapsed)
			if FireHack then
				self:OnFireHack()
				this:Hide()
			end
		end)
	end
	-- Event Register ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	ADDON:RegisterEvent('UPDATE_BINDINGS')

	self:Update()
	self:Print("v"..ADDON.VERSION.." Loaded.")
end
function ADDON:OnEnable()

end
function ADDON:OnDisable()

end
function ADDON:OnFireHack()
	ADDON.Remote:SetStatus('ready')
	ADDON.Engine:OnFireHack()
	ADDON.Tracker:OnFireHack()
	ADDON.RotationSelecter:OnFireHack()
end


-- | ADDON Update |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ADDON:ProfileUpdate()
	self.db = AceDB:New(AddOnName.."DB", self.defaults, true);
	self.db.RegisterCallback(self, "OnProfileChanged", "ProfileUpdate")
	self.db.RegisterCallback(self, "OnProfileCopied", "ProfileUpdate")
	self.db.RegisterCallback(self, "OnProfileReset", "ProfileUpdate")
	-- ~~ Update Database Pointers ~~~~~~~~~~~~~~~~
	self.Remote.db = ADDON.db.profile.remote
	self.RotationSelecter.db = ADDON.db.profile.rotationSelecter
	self.Engine.db = ADDON.db.profile.engine
	self.ActionLog.db = ADDON.db.profile.actionLog
	self.Tracker.db = ADDON.db.profile.tracker

	self:Update()
end
function ADDON:Update()
	if not ADDON:IsEnabled() then return false end

	if self.db.global.minimap.hide then	LibDBIcon:Hide(AddOnName) else LibDBIcon:Show(AddOnName) end

	self.Remote:Update()
	self.Engine:Update()
	self.RotationSelecter:Update()
	self.ActionLog:Update()
	self.Tracker:Update()
end